package com.example.zqh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.zqh.controller.UserPermissionConnectController;
import com.example.zqh.mapper.*;
import com.example.zqh.model.RespBean;
import com.example.zqh.pojo.*;
import com.example.zqh.pojo.params.*;
import com.example.zqh.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.zqh.utils.AssertUtil;
import com.example.zqh.utils.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.repository.core.support.ReactiveRepositoryFactorySupport;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zqh
 * @since 2022-09-10
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    UserDetailsServiceImpl userDetailsServiceImpl;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    UserMapper userMapper;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    JwtTokenUtil jwtTokenUtil;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private FoodMapper foodMapper;

    @Autowired
    UserPermissionConnectMapper userPermissionConnectMapper;

    @Autowired
    CommentMapper commentMapper;


    
    /**
      * @Author: zqh
      * @Date: 
      * @Description: 用户登录接口
    */
    @Override
    @Transactional(readOnly = true)
    public RespBean login(Login login) {
        UserDetails userDetails = userDetailsServiceImpl.loadUserByUsername(login.getUsername());

        //判断用户名密码是否正确
        AssertUtil.isTrue(userDetails == null,"用户名错误");
        AssertUtil.isTrue(!(passwordEncoder.matches(login.getPassword(), userDetails.getPassword())),"密码错误");

        //把用户的权限保存下来
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        //生成token
        String token = jwtTokenUtil.generateToken(userDetails);
        Map<String,String> tokenMap = new HashMap<>();
        tokenMap.put("token",token);
        tokenMap.put("tokenHead",tokenHead);
        return RespBean.success("登录成功",tokenMap);
    }

    @Override
    @Transactional(readOnly = true)
    public RespBean getInfo(Principal principal) {
        String name = principal.getName();
        AssertUtil.isTrue(name == null,"非法操作");
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name));
        //密码解密返回

        return RespBean.success("查询成功",user);
    }
    
    /**
      * @Author: zqh
      * @Date: 
      * @Description: 添加一个新用户
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean registeredUser(RegisterParams registerParams) {
        System.out.println(registerParams.getName());
        System.out.println(registerParams.getPassword()+"352789231578897789");
        //判断用户名是否存在
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", registerParams.getName()));
        AssertUtil.isTrue(user != null,"用户名已存在");
        //判断电话号码是否重复
        User user1 = userMapper.selectOne(new QueryWrapper<User>().eq("phone", registerParams.getPhone()));
        AssertUtil.isTrue(user1 != null||"".equals(registerParams.getPhone()),"电话号码已经存在");



        //判断接口过来的密码不能为空
//        AssertUtil.isTrue("".equals(registerParams.getPassword()),"密码不能为空");
        //添加新用户
        User user2 = new User();
        user2.setName(registerParams.getName())
                //默认设置
                .setAge(18)
                //默认设置
                .setHeadUrl("http://60.205.253.99:9000/zqh/11de1a52-0c10-4b68-aaa4-97704efacc6c.jpg")
                //密码加密
                .setPassword((passwordEncoder.encode(registerParams.getPassword())))
                //默认设置
                .setAddress("====================")
                //默认设置
                .setMoney(0.0)
                //默认设置
                .setIntro("=====================")
                .setSex(registerParams.getSex())
                .setPhone(registerParams.getPhone());

        int insert = userMapper.insert(user2);
        AssertUtil.isTrue(insert != 1,"添加新用户失败");
        User user3 = userMapper.selectOne(new QueryWrapper<User>().eq("name", registerParams.getName()));
        //添加用户成功以后，给他一个ROLE_user权限
        UserPermissionConnect userPermissionConnect = new UserPermissionConnect();
        userPermissionConnect.setUserId(user3.getId())
                .setPermissionId(2);

        int insert1 = userPermissionConnectMapper.insert(userPermissionConnect);
        AssertUtil.isTrue(insert1 != 1,"添加新用户失败");
        return RespBean.success("添加新用户成功");
    }

    @Override
    @Transactional(readOnly = true)
    public RespBean userQueryInterface(Integer page,Integer size) {
        if (page == null && size == null){
            List<User> users = userMapper.selectList(null);
            return RespBean.success("查询成功",users);
        }else {
            List<User> users = userMapper.pagingQueryUsers((page-1)*size, size);
            return RespBean.success("查询成功",users);
        }

    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 用户删除接口
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean userDeleteInterface(Integer id) {
        //删除其在权限表里的数据
        userPermissionConnectMapper.delete(new QueryWrapper<UserPermissionConnect>().eq("user_id", id));

        Shop shop = shopMapper.selectOne(new QueryWrapper<Shop>().eq("user_id", id));
        //删除其店铺的菜品
        int shop_id = foodMapper.delete(new QueryWrapper<Food>().eq("shop_id", shop.getId()));
        AssertUtil.isTrue(shop_id != 1,"用户删除失败");
        //删除去开创的店铺
        int user_id1 = shopMapper.delete(new QueryWrapper<Shop>().eq("user_id", id));
        AssertUtil.isTrue(user_id1 != 1,"用户删除失败");

        //删除用户的所有评论
        int user_id = commentMapper.delete(new QueryWrapper<Comment>().eq("user_id", id));
        AssertUtil.isTrue(user_id != 1,"用户删除失败");

        //删除用户
        int i = userMapper.deleteById(id);
        AssertUtil.isTrue(i != 1,"用户删除失败");


        return RespBean.success("用户删除成功");
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 管理员修改用户接口
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean adminModifyUserInformation(User user) {
        //数据库中原有的数据
        User user1 = userMapper.selectById(user.getId());
        //电话号码是否改变了
        if (!user.getPhone().equals(user1.getPhone())){
            //电话号码改变了
            User user2 = userMapper.selectOne(new QueryWrapper<User>().eq("phone", user.getPhone()));
            AssertUtil.isTrue(user2 != null,"你修改的电话号码已经存在");
        }
        //用户名是否改变了
        if (!user.getName().equals(user1.getName())){
            User user2 = userMapper.selectOne(new QueryWrapper<User>().eq("name", user.getName()));
            AssertUtil.isTrue(user2 != null,"此用户名已存在，无法修改");
        }
        int i = userMapper.updateById(user);
        AssertUtil.isTrue(i != 1,"修改用户信息失败");

        return RespBean.success("修改用户信息成功");
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 用户修改密码接口
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean userChangePasswordInterface(String password, Principal principal) {
        String name = principal.getName();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name));
        AssertUtil.isTrue(user == null,"非法操作");
        //判断输入的密码和原数据库中的是否一致
//        AssertUtil.isTrue(!(passwordEncoder.matches(twoString.getOldWord(),user.getPassword())),"原密码输入错误");

        //判断两次输入的密码是否一致
//        AssertUtil.isTrue(!(twoString.getOldWord().equals(twoString.getNewWord())),"你两次输入的密码不一样");

        //修改原密码
        user.setPassword(passwordEncoder.encode(password));
        int i = userMapper.updateById(user);
        AssertUtil.isTrue(i != 1,"修改密码失败");


        return RespBean.success("密码修改成功");
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 用户修改自己的名字
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean userChangeNameInterface(String nameses, Principal principal) {
        String name = principal.getName();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name));
        AssertUtil.isTrue(user == null,"非法操作");
        User user1 = userMapper.selectOne(new QueryWrapper<User>().eq("name", nameses));
        user.setName(nameses);
        int i = userMapper.updateById(user);
        AssertUtil.isTrue(i != 1,"修改用户名失败");
        return RespBean.success("修改用户名成功");
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 修改自己的性别
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean userChangeSexInterface(Integer sex, Principal principal) {
        String name = principal.getName();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name));
        AssertUtil.isTrue(user == null,"非法操作");
        user.setSex(sex);
        int i = userMapper.updateById(user);
        AssertUtil.isTrue(i != 1,"修改性别失败");
        return RespBean.success("修改性别成功");
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 修改自己的头像
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean userChangeHeadurlInterface(String headUrl, Principal principal) {
        String name = principal.getName();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name));
        AssertUtil.isTrue(user == null,"非法操作");
        //修改评论表中用户的头像
        List<Comment> comments = commentMapper.selectList(new QueryWrapper<Comment>().eq("user_id", user.getId()));
        for (Comment comment : comments) {
            comment.setUserpic(headUrl);
            int i = commentMapper.updateById(comment);
            AssertUtil.isTrue(i != 1,"头像修改失败");
        }
        user.setHeadUrl(headUrl);
        int i = userMapper.updateById(user);
        AssertUtil.isTrue(i != 1,"修改头像失败");
        return RespBean.success("修改头像成功");
    }


    /**
      * @Author: zqh
      * @Date:
      * @Description: 修改自己的电话号码
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean userChangePhoneInterface(String phone, Principal principal) {
        String name = principal.getName();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name));
        AssertUtil.isTrue(user == null,"非法操作");
        User user1 = userMapper.selectOne(new QueryWrapper<User>().eq("phone", phone));
        AssertUtil.isTrue(user1 != null,"该电话号码已存在，无法修改");
        user.setPhone(phone);
        int i = userMapper.updateById(user);
        AssertUtil.isTrue(i != 1,"修改电话号码失败");
        return RespBean.success("修改电话号码成功");
    }


    /**
      * @Author: zqh
      * @Date:
      * @Description: 修改自己的年龄
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean userChangeAgeInterface(Integer age, Principal principal) {
        String name = principal.getName();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name));
        AssertUtil.isTrue(user == null,"非法操作");
        user.setAge(age);
        int i = userMapper.updateById(user);
        AssertUtil.isTrue(i!=1,"修改年龄失败");
        return RespBean.success("修改年龄成功");
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 充值接口
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean rechargeInterface(Integer money, Principal principal) {
        String name = principal.getName();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name));
        AssertUtil.isTrue(user == null,"非法操作");
//        Double x = user.getMoney() + Double.valueOf(String.valueOf(oneNumber));
        Double x = user.getMoney() + money;
        user.setMoney(x);
        int i = userMapper.updateById(user);
        AssertUtil.isTrue(i != 1,"充值失败");
        return RespBean.success("充值成功");
    }


    /**
      * @Author: zqh
      * @Date:
      * @Description: 修改自我简介
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean userChangeIntroInterface(String intro, Principal principal) {
        String name = principal.getName();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name));
        AssertUtil.isTrue(user == null,"非法操作");
        user.setIntro(intro);
        int i = userMapper.updateById(user);
        AssertUtil.isTrue(i != 1,"修改自我简介失败");
        return RespBean.success("修改自我简介成功");
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 获取所有用户的数量
    */
    @Override
    @Transactional(readOnly = true)
    public RespBean getTheCountOfAllUsers() {
        Integer number = userMapper.getAllUserNumber();
        return RespBean.success("查询成功",number);
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 模糊查询用户
    */
    @Override
    @Transactional(readOnly = true)
    public RespBean fuzzyQueryUsersByZ(String oneString) {
        String text = oneString;
        AssertUtil.isTrue(text == null,"请输入关键词");
        text += "%";
        List<User> users = userMapper.fuzzyQueryUser(text);
        return RespBean.success("查询成功",users);
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 通过性别查询数量
    */
    @Override
    @Transactional(readOnly = true)
    public RespBean getNumberBySex(Integer sex) {
        Integer numberBySex = userMapper.getNumberBySex(sex);
        return RespBean.success("查询成功",numberBySex);
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 通过性别查询id，并且带分页查询
    */
    @Override
    @Transactional(readOnly = true)
    public RespBean getUsersBySexAndPageing(Integer sex, Integer page, Integer size) {
        page = (page - 1) * size;
        List<User> users = userMapper.queryUsersByGenderAndQueryByPagination(sex, page, size);
        return RespBean.success("查询成功",users);
    }


    /**
      * @Author: zqh
      * @Date:
      * @Description: 修改自我地址
    */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public RespBean modifySelfAddress(String address, Principal principal) {
        String name = principal.getName();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name));
        AssertUtil.isTrue(user == null,"非法操作");
        user.setAddress(address);
        int i = userMapper.updateById(user);
        AssertUtil.isTrue(i != 1,"修改地址失败");
        return RespBean.success("修改地址成功");
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 通过id查询用户的信息
    */
    @Override
    @Transactional(readOnly = true)
    public RespBean queryUserInformationById(Integer id) {
        User user = userMapper.selectById(id);
        return RespBean.success("查询成功",user);
    }

    @Override
    @Transactional(readOnly = true)
    public RespBean adminLogin(Login login) {
        int i = 0;
        List<String> roleCodeByUsername = userMapper.getRoleCodeByUsername(login.getUsername());
        for (String s : roleCodeByUsername) {
            if (s.equals("ROLE_admin")){
                i += 1;
            }
        }
        if (i == 1) {
            UserDetails userDetails = userDetailsServiceImpl.loadUserByUsername(login.getUsername());

            //判断用户名密码是否正确
            AssertUtil.isTrue(userDetails == null, "用户名错误");
            AssertUtil.isTrue(!(passwordEncoder.matches(login.getPassword(), userDetails.getPassword())), "密码错误");

            //把用户的权限保存下来
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);

            //生成token
            String token = jwtTokenUtil.generateToken(userDetails);
            Map<String, String> tokenMap = new HashMap<>();
            tokenMap.put("token", token);
            tokenMap.put("tokenHead", tokenHead);
            return RespBean.success("登录成功", tokenMap);
        }else {
            return RespBean.error("权限不够");
        }

    }
}
